package com.springsummer.information.green.webmvc;

import com.alibaba.fastjson.JSON;

import java.io.*;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;

public class HttpServerRequestHandler implements Runnable{

    private Socket socket;

    private final Map<String, String> responseHeaders = new HashMap<>();
    private String responseBody = "";
    private String responseStatus = "200 OK";

    private final ConcurrentMap<String, ConnectionHandle> connectionHandleMap;


    public HttpServerRequestHandler(Socket socket) {
        this.socket = socket;
        this.connectionHandleMap=new ConcurrentHashMap<>();
        this.initHandleMapping();
    }

    public void initHandleMapping(){
        this.connectionHandleMap.put("/user/add",new UserAddConnectionHandleImpl());
        this.connectionHandleMap.put("/user/list",new UserListConnectionHandleImpl());
        this.connectionHandleMap.put("/order/add",new OrderAddConnectionHandleImpl());
        this.connectionHandleMap.put("/order/list",new OrderListConnectionHandleImpl());
        this.connectionHandleMap.put("/student/add",new StudentAddConnectionHandleImpl());
        this.connectionHandleMap.put("/student/list",new StudentListConnectionHandleImpl());
        //System.out.println("initHandleMapping:");
        //System.out.println(JSON.toJSONString(this.connectionHandleMap));
    }

    @Override
    public void run() {
        try (InputStream inputStream=socket.getInputStream();
             BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
             OutputStream out = socket.getOutputStream()) {

            // 读取请求头
            String requestLine = in.readLine();
            if (requestLine == null) {return;}

            // 解析请求方法
            String method = parseMethod(requestLine);
            System.out.println("Method: " + method);

            // 解析请求URL
            String url = parseUrl(requestLine);
            System.out.println("URL: " + url);

            // 解析请求头
            Map<String, String> headers = parseHeaders(in);
            System.out.println("Headers: " + headers);

            // 解析GET参数
            String urlRaw = requestLine.split(" ")[1];
            Map<String, String> getParams = parseGetParam(urlRaw);
            System.out.println("GET Parameters: " + getParams);

            // 解析POST参数
            Map<String, String> postParams = new LinkedHashMap<>();
            if ("POST".equalsIgnoreCase(method)) {
                postParams = parsePostParam(in, headers);
                System.out.println("POST Parameters: " + postParams);
            }

            // 构建响应
            //String response = buildResponse(method, url, headers, getParams, postParams);
            //out.write(response.getBytes());

            // 构建响应

            //setResponseContentType("text/html; charset=utf-8");
            addResponseHeader("Connection", "keep-alive");
            addResponseHeader("Server","JavaServer/1.1");

            //prepareResponseBody(method, url, headers, getParams, postParams);
            //String htmlBody=buildHtmlResponseBody(method,url,headers,getParams,postParams);

            String outBodyContent=handleDispatch(url);

            String htmlContent = "<html><body><h2 style=\"\n" +
                    "    color: blue;\n" +
                    "\"  >hello " + outBodyContent + "</h2></body></html>";
            //byte[] htmlBytes = htmlContent.getBytes(StandardCharsets.UTF_8);

            Map<String,String> userMap=new LinkedHashMap<>();
            userMap.put("name","zhangshanshan");
            userMap.put("age","20");

            //outBody(htmlContent);

            boolean outJson=false;
            if(outJson){
                setResponseContentType(WebConstant.defaultContentType);
                outBody(JSON.toJSONString(userMap));
            }else{
                setResponseContentType("text/html; charset=utf-8");
                outBody(htmlContent);
            }


            addResponseHeader("Content-Length", String.valueOf(responseBody.length()));

            // 输出响应
            sendResponse(out);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public  String handleDispatch(String parsedUrl){
        Logger.getGlobal().info("handleDispatch url:"+parsedUrl);
        ConnectionHandle connectionHandle=null;
        if(parsedUrl.contains("/user/add")){
            //connectionHandle=new UserAddConnectionHandleImpl();
            connectionHandle=connectionHandleMap.get("/user/add");
        }else if(parsedUrl.contains("/user/list")){
            //connectionHandle=new UserListConnectionHandleImpl();
            connectionHandle=connectionHandleMap.get("/user/list");
        }else if(parsedUrl.contains("/order/add")){
            connectionHandle=connectionHandleMap.get("/order/add");
        }else if(parsedUrl.contains("/order/list")){
            connectionHandle=connectionHandleMap.get("/order/list");
        }else if(parsedUrl.contains("/student/add")){
            connectionHandle=connectionHandleMap.get("/student/add");
        }else if(parsedUrl.contains("/student/list")){
            connectionHandle=connectionHandleMap.get("/student/list");
        }else{ //default
            connectionHandle=new UserListConnectionHandleImpl();
        }
        String handleResult= connectionHandle.handle(parsedUrl);
        String body=parsedUrl+" \r\n</br> "+handleResult+" ";
        return body;
    }

    private String parseMethod(String requestLine) {
        return requestLine.split(" ")[0];
    }

    private String parseUrl(String requestLine) {
        String url = requestLine.split(" ")[1];
        return url.contains("?") ? url.split("\\?")[0] : url;
    }

    private Map<String, String> parseHeaders(BufferedReader in) throws Exception {
        Map<String, String> headers = new HashMap<>();
        String line;
        while ((line = in.readLine()) != null) {
            if (line.isEmpty()) break;
            int colonIndex = line.indexOf(":");
            if (colonIndex > 0) {
                String key = line.substring(0, colonIndex).trim();
                String value = line.substring(colonIndex + 1).trim();
                headers.put(key, value);
            }
        }
        return headers;
    }

    private Map<String, String> parseGetParam(String url) {
        Map<String, String> params = new HashMap<>();
        if (url.contains("?")) {
            String query = url.split("\\?")[1];
            parseQueryString(query, params);
        }
        return params;
    }

    private Map<String, String> parsePostParam(BufferedReader in, Map<String, String> headers) throws IOException {
        Map<String, String> params = new HashMap<>();
        int contentLength = Integer.parseInt(headers.getOrDefault("Content-Length", "0"));
        if (contentLength > 0) {
            char[] body = new char[contentLength];
            in.read(body);
            parseQueryString(new String(body), params);
        }
        return params;
    }

    private void parseQueryString(String query, Map<String, String> params) {
        try {
            for (String pair : query.split("&")) {
                int idx = pair.indexOf("=");
                String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
                String value = idx > 0 && pair.length() > idx + 1 ?
                        URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : "";
                params.put(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String buildHtmlResponseBody(String method, String url, Map<String, String> headers,
                                 Map<String, String> getParams, Map<String, String> postParams) {
        String htmlBody = "<html><body>" +
                "<h1>HTTP Server Response</h1>" +
                "<h2>Request Info</h2>" +
                "<p>Method: " + method + "</p>" +
                "<p>URL: " + url + "</p>" +
                "<h3>Headers</h3><ul><li>hello1</li>" +
                "</ul></body></html>";

//        return "HTTP/1.1 200 OK\r\n" +
//                "Content-Type: text/html\r\n" +
//                "Content-Length: " + html.length() + "\r\n" +
//                "Connection: close\r\n\r\n" +
//                html;


        return htmlBody;
    }

    // 新增响应处理方法
    public void setResponseContentType(String contentType) {
        addResponseHeader("Content-Type", contentType);
    }

    public void addResponseHeader(String name, String value) {
        responseHeaders.put(name, value);
    }

    public void outBody(String body) {
        this.responseBody = body;
    }

    private void sendResponse(OutputStream out) throws IOException {
        String headers = buildResponseHeaders();
        out.write(("HTTP/1.1 " + responseStatus + "\r\n").getBytes());
        out.write(headers.getBytes());
        out.write("\r\n".getBytes());
        out.write(responseBody.getBytes());
        out.flush();
    }

    private String buildResponseHeaders() {
        StringJoiner stringJoiner=new StringJoiner("\r\n");
        for(Map.Entry<String,String> entry: responseHeaders.entrySet()){
            String hstr=entry.getKey() + ": " + entry.getValue();
            stringJoiner.add(hstr);
        }
        String headersStr=stringJoiner.toString()+ "\r\n";

//        return responseHeaders.entrySet().stream()
//                .map(entry -> entry.getKey() + ": " + entry.getValue())
//                .collect(Collectors.joining("\r\n")) + "\r\n";
        return headersStr;
    }





}
